home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1999 November / Macworld (1999-11).dmg / Updaters / WhiteCap 3.0.4 / WhiteCap Source.sit / WhiteCap Source / Common / EgOSUtils.cpp next >
C/C++ Source or Header  |  1999-08-01  |  12KB  |  598 lines

  1. #include "EgOSUtils.h"
  2.  
  3. #include "CEgFileSpec.h"
  4. #include "CEgErr.h"
  5. #include "UtilStr.h"
  6.  
  7. #include <stdlib.h>
  8. #include <time.h>
  9.  
  10. #ifdef EG_MAC
  11. #include <Resources.h>
  12. #include <Sound.h>
  13. #endif
  14.  
  15.  
  16. #ifdef EG_WIN
  17. #include <windows.h>
  18. #endif
  19.  
  20.  
  21.  
  22. int                EgOSUtils::sXdpi                = 72;
  23. int                EgOSUtils::sYdpi                = 72;
  24. long            EgOSUtils::sLastCursor            = -1;
  25. long            EgOSUtils::sLastCursorChange     = -1;
  26. CEgFileSpec     EgOSUtils::sAppSpec;
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33. void EgOSUtils::ShowFileErr( const UtilStr* inName, char* inErrMsg, bool wasReading ) {
  34.     UtilStr    s;
  35.     
  36.     if ( wasReading ) 
  37.         s.Assign( "Error reading : " );
  38.     else
  39.         s.Assign( "Error writing : " );
  40.     s.Append( inErrMsg );
  41.     
  42.     #ifdef EG_MAC
  43.     s.Insert( 14, "“”" );
  44.     #else
  45.     s.Insert( 14, "\"\"" );
  46.     #endif
  47.         
  48.     s.Insert( 15, inName );    
  49.     ShowMsg( s );
  50. }
  51.  
  52.  
  53. void EgOSUtils::ShowFileErr( const UtilStr* inName, CEgErr& inErr, bool wasReading ) {
  54.     UtilStr    msg;
  55.     
  56.     inErr.GetErrStr( msg );
  57.     ShowFileErr( inName, msg.getCStr(), wasReading );
  58. }
  59.  
  60.  
  61.  
  62. void EgOSUtils::ShowFileErr( const CEgFileSpec& inFileSpec, CEgErr& inErr, bool wasReading ) {
  63.     UtilStr    msg, fileName;
  64.     
  65.     inFileSpec.GetFileName( fileName  );
  66.     inErr.GetErrStr( msg );
  67.     ShowFileErr( &fileName, msg.getCStr(), wasReading );
  68. }
  69.  
  70.  
  71.  
  72.  
  73.  
  74. void EgOSUtils::Initialize() {
  75.     
  76.     srand( clock() );
  77.     
  78.     #if EG_MAC
  79.     OSStatus    status;
  80.     FCBPBRec    fcbPBRec;
  81.     Str255        appName;
  82.     FSSpec        spec;
  83.     
  84.     fcbPBRec.ioCompletion    = nil;
  85.     fcbPBRec.ioFCBIndx        = 0;
  86.     fcbPBRec.ioVRefNum        = 0;
  87.     fcbPBRec.ioRefNum        = ::CurResFile();
  88.     fcbPBRec.ioNamePtr        = appName;
  89.     
  90.     status = ::PBGetFCBInfoSync(&fcbPBRec);
  91.     
  92.     ::FSMakeFSSpec(fcbPBRec.ioFCBVRefNum, fcbPBRec.ioFCBParID, appName, &spec );
  93.     sAppSpec.Assign( &spec, 0 );
  94.     #endif
  95.     
  96.     #ifdef EG_WIN
  97.     HDC    hDC = ::CreateDC( "DISPLAY", NULL, NULL, NULL );
  98.     if ( hDC ) {
  99.         sXdpi = ::GetDeviceCaps( hDC, LOGPIXELSX );
  100.         sYdpi = ::GetDeviceCaps( hDC, LOGPIXELSY );
  101.         ::DeleteDC( hDC );
  102.     }
  103.     
  104.     char path[ 700 ];
  105.     long len = ::GetModuleFileName( NULL, path, 699 );
  106.     if ( len ) {
  107.         UtilStr fdir( path, len );
  108.         fdir.Keep( fdir.FindLastInstanceOf( '\\' ) );
  109.         sAppSpec.Assign( fdir.getCStr(), 0 );
  110.     }
  111.     
  112.     /*
  113.     UtilStr prefPath;
  114.     char path[ 500 ];
  115.     if ( ::GetCurrentDirectory( 495, path ) ) {
  116.         prefPath.Assign( path );
  117.         prefPath.Append( '\\' );
  118.         sAppSpec.Assign( prefPath.getCStr(), 0 );
  119.     }*/
  120.     #endif
  121.     
  122.     // For mac, sXspi and sYdpi are already correct by default
  123. }
  124.  
  125.  
  126.  
  127.                 
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137. bool EgOSUtils::AskSaveAs( const char* inPrompt, const char* inDefaultName, CEgFileSpec& outSpec, long inFileType ) {
  138.     UtilStr inName( inDefaultName );
  139.     
  140.     return AskSaveAs( inPrompt, inName, outSpec, inFileType );
  141. }
  142.  
  143.  
  144. #ifdef EG_ZINC
  145. #include <z_fildlg.hpp>
  146. #endif
  147.  
  148.  
  149.  
  150.  
  151. bool EgOSUtils::AskSaveAs( const char* inPrompt, const UtilStr& inDefaultName, CEgFileSpec& outSpec, long inFileType ) {
  152.     int    doSave = false;
  153.     UtilStr prompt( inPrompt );
  154.  
  155.     #ifdef EG_MAC
  156.     StandardFileReply    reply;
  157.     
  158.     //::UDesktop::Deactivate();
  159.     ::StandardPutFile( prompt.getPasStr(), inDefaultName.getPasStr(), &reply );
  160.     //::UDesktop::Activate();
  161.     
  162.     if (reply.sfGood) {        
  163.         outSpec.Assign( &reply.sfFile, inFileType );
  164.         doSave = true;
  165.     }
  166.     #endif
  167.     
  168.     #if EG_WIN && EG_ZINC
  169.     UtilStr defName( inDefaultName );
  170.     
  171.     ZafFileDialog    fileDialog( 20, 5, 60, 14 );
  172.     
  173.     if ( inFileType ) 
  174.         CEgFileSpec::TypeToExt( defName, inFileType );
  175.  
  176.     fileDialog.SetFile( defName.getCStr()  );
  177.     
  178.     if ( fileDialog.GetFile( ZAF_FILE_DIALOG_SAVEAS ) == S_DLG_OK ) {
  179.         doSave = true;
  180.         outSpec.Assign( fileDialog.File(), inFileType );
  181.     }
  182.     /*
  183.     unsigned char    c;
  184.     UtilStr        winFilter;
  185.     OPENFILENAME     paramBlk;
  186.     char            pathName[ 601 ];
  187.     
  188.     inDefaultName.copyTo( pathName, 600 );
  189.  
  190.     // See page 519 of Vol 5 in Win32 Ref for descrip of the lpstrFilter scheme.
  191.     winFilter.Append( "/0*" );    
  192.     
  193.     // Append the ext mask...
  194.     for ( int d = 0; d <= 24; d += 8 ) {            // Go thru each byte in ID num
  195.         c = ((inFileType << d) >> 24 );
  196.         winFilter.Append( (char) c );
  197.     }
  198.     winFilter.Append( (char) 0 );                    // Windows exptects an extra NUL to end the filter
  199.  
  200.     memset( ¶mBlk, 0, sizeof(OPENFILENAME) );
  201.     paramBlk.lStructSize = sizeof(OPENFILENAME);
  202.     paramBlk.lpstrFilter        = winFilter.getCStr();
  203.     paramBlk.lpstrFile            = pathName;
  204.     paramBlk.nMaxFile            = 600;
  205.     paramBlk.lpstrTitle            = prompt.getCStr();
  206.     if ( ::GetSaveFileName( ¶mBlk ) ) {
  207.         outSpec.Assign( pathName );
  208.         doSave = true; 
  209.     }*/
  210.     #endif
  211.     
  212.     return doSave;
  213. }
  214.  
  215.  
  216.  
  217.  
  218. bool EgOSUtils::AskOpen( const char* inPrompt, CEgFileSpec& outSpec, long inTypeMask ) {
  219.     bool didOpen = false;
  220.     UtilStr prompt( inPrompt );
  221.  
  222.     #ifdef EG_MAC
  223.     StandardFileReply    macFileReply;
  224.     SFTypeList            typeList;
  225.     
  226.     //UDesktop::Deactivate();
  227.     typeList[0] = inTypeMask;
  228.     ::StandardGetFile( NULL, inTypeMask ? 1 : 0, typeList, &macFileReply );
  229.     //UDesktop::Activate();
  230.  
  231.     if ( macFileReply.sfGood ) {
  232.         outSpec.Assign( &macFileReply.sfFile );
  233.         didOpen = true;
  234.     }
  235.     #endif
  236.     
  237.     #if EG_WIN && EG_ZINC
  238.     ZafFileDialog    fileDialog( 5, 5, 60, 14 );
  239.     UtilStr        str( "*" );
  240.     
  241.     if ( inTypeMask ) {
  242.         CEgFileSpec::TypeToExt( str, inTypeMask );
  243.         fileDialog.SetFilter( str.getCStr() );
  244.     }
  245.     
  246.     if ( fileDialog.GetFile( ZAF_FILE_DIALOG_OPEN ) == S_DLG_OK ) {
  247.         char path[ 401 ];
  248.         didOpen = true;
  249.  
  250.         fileDialog.FullPath( path, 400 );
  251.         outSpec.Assign( path );
  252.     }    
  253.     /*
  254.     unsigned char    c;
  255.     UtilStr        winFilter;
  256.     OPENFILENAME     paramBlk;
  257.     char            pathName[ 601 ];
  258.     
  259.     // See page 519 of Vol 5 in Win32 Ref for descrip of the lpstrFilter scheme.
  260.     winFilter.Append( "/0*" );    
  261.     
  262.     // Append the ext mask...
  263.     for ( int d = 0; d <= 24; d += 8 ) {            // Go thru each byte in ID num
  264.         c = ((inTypeMask << d) >> 24 );
  265.         winFilter.Append( (char) c );
  266.     }
  267.     winFilter.Append( (char) 0 );                    // Windows exptects an extra NUL to end the filter
  268.  
  269.     memset( ¶mBlk, 0, sizeof(OPENFILENAME) );
  270.     paramBlk.lStructSize = sizeof(OPENFILENAME);
  271.     paramBlk.lpstrFilter        = winFilter.getCStr();
  272.     paramBlk.lpstrFile            = pathName;
  273.     paramBlk.nMaxFile            = 600;
  274.     paramBlk.lpstrTitle            = prompt.getCStr();
  275.     if ( ::GetOpenFileName( ¶mBlk ) ) {
  276.         outSpec.Assign( pathName );
  277.         didOpen = true; 
  278.     }*/
  279.     #endif
  280.     
  281.     return didOpen;
  282. }
  283.  
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290.  
  291. bool EgOSUtils::AreYouSure( const UtilStr& inMsg ) {
  292.     int ans;
  293.     
  294.     #ifdef EG_MAC
  295.     ::ParamText( inMsg.getPasStr(), "\p", "\p", "\p");
  296.     //UDesktop::Deactivate();
  297.     ans = ::CautionAlert( 2000, NULL );
  298.     //UDesktop::Activate();
  299.     
  300.     return ans == 1; //answer_Save;
  301.     #endif
  302.     
  303.     #ifdef EG_WIN
  304.     ans = ::MessageBox( NULL, inMsg.getCStr(), "Examgen Message", MB_ICONEXCLAMATION | MB_YESNO | MB_SETFOREGROUND | MB_TASKMODAL );
  305.     return ans == IDYES;
  306.     #endif
  307. }    
  308.  
  309.  
  310. bool EgOSUtils::AreYouSure( const char* inMsg ) {
  311.     UtilStr    msg( inMsg );
  312.     
  313.     return AreYouSure( msg );
  314. }
  315.  
  316.  
  317.  
  318. int EgOSUtils::AskSaveChanges( const char* inName ) {
  319.     UtilStr name( inName );
  320.     return AskSaveChanges( name );
  321. }
  322.  
  323.  
  324.  
  325. int EgOSUtils::AskSaveChanges( const UtilStr& inName ) {
  326.     int ans;
  327.     
  328.     #ifdef EG_MAC
  329.     ::ParamText( inName.getPasStr(), "\p", "\p", "\p" );
  330.     //UDesktop::Deactivate();
  331.     ans = ::CautionAlert( 2001, NULL );
  332.     //UDesktop::Activate();
  333.         
  334.     return 2 - ans;
  335.     #endif
  336.     
  337.     #ifdef EG_WIN
  338.     UtilStr    msg( "Save changes to \"" );
  339.     msg.Append( inName );
  340.     msg.Append( "\" before closing?" );
  341.     ans = ::MessageBox( NULL, msg.getCStr(), "Examgen Message", MB_ICONEXCLAMATION | MB_YESNOCANCEL | MB_SETFOREGROUND | MB_TASKMODAL );
  342.     if ( ans == IDYES )
  343.         return 1;
  344.     else if ( ans == IDNO )
  345.         return -1;
  346.     else
  347.         return 0;
  348.     #endif
  349. }
  350.  
  351.  
  352. void EgOSUtils::SpinCursor() {
  353.     long time = clock();
  354.     
  355.     if ( sLastCursorChange == -1 )
  356.         sLastCursorChange = time;
  357.     else if ( time - CLOCKS_PER_SEC / 3 > sLastCursorChange ) {                    // Every 1/3 second...
  358.         #ifdef EG_MAC
  359.         Handle cursHndl;
  360.         sLastCursor            = ( sLastCursor + 1 ) % 8;                            // 8 Cursors
  361.         cursHndl            = ::GetResource( 'CURS', 6500 + sLastCursor );        // 6500 = Base ID
  362.         sLastCursorChange    = time;
  363.         if ( cursHndl )
  364.             ::SetCursor( (Cursor*) *cursHndl );
  365.         #endif
  366.         
  367.         #ifdef EG_WIN
  368.         SetCursor( ::LoadCursor( NULL, IDC_WAIT ) );
  369.         sLastCursor = 1;
  370.         #endif
  371.     }
  372. }
  373.  
  374.  
  375.  
  376.  
  377.  
  378.  
  379.  
  380.  
  381. void EgOSUtils::ShowCursor() {
  382.  
  383.     #ifdef EG_MAC
  384.     ::ShowCursor();
  385.     ::InitCursor();
  386.     #endif
  387.     
  388.     #ifdef EG_WIN
  389.     ::SetCursor( ::LoadCursor( NULL, IDC_ARROW ) );
  390.     while ( ::ShowCursor( true ) < 0 ) { }
  391.     #endif
  392.     
  393.     sLastCursor            = -1;
  394.     sLastCursorChange    = -1;
  395. }
  396.  
  397.  
  398. void EgOSUtils::HideCursor() {
  399.  
  400.     #ifdef EG_MAC
  401.     ::HideCursor();
  402.     #endif
  403.     
  404.     #ifdef EG_WIN
  405.     while ( ::ShowCursor( false ) >= 0 ) { }
  406.     #endif
  407.         
  408.     sLastCursor            = -1;
  409.     sLastCursorChange    = -1;
  410. }
  411.  
  412.  
  413.  
  414. bool EgOSUtils::GetNextFile( const CEgFileSpec& folderSpec, CEgFileSpec& outSpec, bool inStartOver, bool inFolders ) {
  415.     bool ok;
  416.     
  417.     #ifdef EG_MAC
  418.     static int            sLastIndex;
  419.     OSErr                err;
  420.     HFileInfo            pb;
  421.     FSSpec                spec;
  422.     long                parID;
  423.     Str255                str;
  424.     
  425.     parID            = ( (FSSpec*) folderSpec.OSSpec() ) -> parID;
  426.     pb.ioVRefNum    = ( (FSSpec*) folderSpec.OSSpec() ) -> vRefNum;
  427.     pb.ioNamePtr     = str;
  428.     
  429.     if ( inStartOver )
  430.         pb.ioFDirIndex = 1;
  431.     else
  432.         pb.ioFDirIndex = sLastIndex;
  433.     
  434.     ok = false;
  435.     do {
  436.         pb.ioDirID     = parID;
  437.         err = PBGetCatInfoSync( (CInfoPBRec*) &pb );
  438.         
  439.         if ( err == noErr && ( (pb.ioFlFndrInfo.fdFlags & fInvisible) == 0)  /*&& pb.ioFlFndrInfo.fdCreator == cEGCreator*/ ) {
  440.             ok = ( (pb.ioFlAttrib & ioDirMask ) == 0 );
  441.             if ( inFolders )
  442.                 ok = ! ok;
  443.             if ( ok ) {
  444.                 if ( inFolders )
  445.                     pb.ioFlParID = pb.ioDirID;
  446.                 ::FSMakeFSSpec( pb.ioVRefNum, pb.ioFlParID, str, &spec );
  447.                 outSpec.Assign( &spec, pb.ioFlFndrInfo.fdType );
  448.             }
  449.         }
  450.         
  451.         pb.ioFDirIndex++;
  452.         sLastIndex = pb.ioFDirIndex;
  453.     } while ( err == noErr && ! ok );
  454.  
  455.     #endif
  456.     
  457.     
  458.  
  459.     #ifdef EG_WIN
  460.     WIN32_FIND_DATA        fileData;
  461.     static HANDLE        hSearch;
  462.     UtilStr                name;
  463.     bool                isDir, tryAgain;
  464.     
  465.     do {
  466.         if ( inStartOver ) {
  467.             inStartOver = false;
  468.             name.Assign( (char*) folderSpec.OSSpec() );
  469.             if ( name.getChar( name.length() ) == '\\' )
  470.                 name.Trunc( 1 );
  471.             ok = SetCurrentDirectory( name.getCStr() );
  472.             if ( ok ) {
  473.                 hSearch = ::FindFirstFile( "*.*", &fileData ); 
  474.                 ok = hSearch != INVALID_HANDLE_VALUE; 
  475.             } }
  476.         else
  477.             ok = ::FindNextFile( hSearch, &fileData );    
  478.         if ( ok ) {
  479.             name.Assign( fileData.cFileName );
  480.             isDir = ::GetFileAttributes( fileData.cFileName ) & FILE_ATTRIBUTE_DIRECTORY;
  481.             if ( isDir == inFolders ) {
  482.                 tryAgain = name.compareTo( "." ) == 0 || name.compareTo( ".." ) == 0;
  483.                 outSpec.Assign( folderSpec );
  484.                 if ( isDir ) 
  485.                     name.Append( "\\" );
  486.                 outSpec.Rename( name ); }
  487.             else
  488.                 tryAgain = true;
  489.         }
  490.     } while ( ok && tryAgain );
  491.     #endif
  492.         
  493.     
  494.     return ok;
  495. }
  496.  
  497.  
  498.  
  499.  
  500.  
  501.  
  502.  
  503.  
  504.  
  505.  
  506. void EgOSUtils::Beep() {
  507.     
  508.     #ifdef EG_MAC
  509.     ::SysBeep( 200 );
  510.     #endif
  511.     
  512.     #ifdef EG_WIN
  513.     MessageBeep(0);
  514.     #endif
  515. }
  516.  
  517.  
  518.  
  519. long EgOSUtils::CurTimeMS() {
  520.     #if EG_WIN
  521.     return ::timeGetTime();
  522.     #else
  523.     return ::TickCount() * 16;
  524.     #endif
  525. }
  526.  
  527.  
  528. void EgOSUtils::GetMouse( Point& outPt ) {
  529.  
  530.     #if EG_MAC
  531.     ::GetMouse( &outPt );
  532.     ::LocalToGlobal( &outPt );
  533.     #endif
  534.  
  535.     #if EG_WIN
  536.     POINT p;
  537.     ::GetCursorPos( &p );
  538.     outPt.h = p.x;
  539.     outPt.v = p.y;
  540.     #endif
  541.  
  542. }
  543.  
  544.  
  545. void EgOSUtils::ShowMsg( const UtilStr& inMsg ) {
  546.  
  547.     #ifdef EG_MAC
  548.     //UDesktop::Deactivate();
  549.     ::ParamText( inMsg.getPasStr(), "\p", "\p", "\p");
  550.     ::StopAlert( 2002, NULL );
  551.     //#pragma rem back in!
  552.     //UDesktop::Activate();
  553.     #endif
  554.     
  555.     #ifdef WIN32
  556.     ::MessageBox( NULL, inMsg.getCStr(), "Examgen Message", MB_ICONEXCLAMATION | MB_OK | MB_SETFOREGROUND | MB_APPLMODAL );
  557.     //ZafMessageWindow* w = new ZafMessageWindow( "Message", ZAF_EXCLAMATION_ICON, ZAF_DIALOG_OK, ZAF_DIALOG_OK, inMsg.getCStr() );
  558.     //zafWindowManager -> Add( w );
  559.     //w -> Control();
  560.     #endif
  561.     
  562. }
  563.  
  564.  
  565.  
  566. void EgOSUtils::ShowMsg( const char* inMsg ) {
  567.     UtilStr msg( inMsg );
  568.     
  569.     ShowMsg( msg );
  570. }
  571.  
  572.  
  573.  
  574. long EgOSUtils::Rnd( long min, long max ) {
  575.     long maxRnd     = RAND_MAX;
  576.     long retNum     = rand() * ( max - min + 1 ) / maxRnd + min;
  577.     
  578.     if ( retNum >= max )
  579.         return max;
  580.     else
  581.         return retNum;
  582. }
  583.  
  584.  
  585.  
  586.  
  587. unsigned long EgOSUtils::RevBytes( unsigned long inNum ) {
  588.  
  589.  
  590.     return ( inNum << 24 ) | ( ( inNum & 0xFF00 ) << 8 ) | ( ( inNum & 0xFF0000 ) >> 8 ) | ( inNum >> 24 );
  591. }
  592.  
  593.  
  594.  
  595.  
  596.  
  597.  
  598.